package com.me.collector;

import java.util.ArrayList;
import java.util.Iterator;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.Shape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.Array;
import com.me.collector.Definitions.EntityCategory;

public class FallingObjectList {

	// ****************************
	// Members
	// ****************************

	private ArrayList<FallingObject> fallingObjects = new ArrayList<FallingObject>();

	private World world;
	private Physics physics;
	private boolean pause = false;
	private Item item;
	
	

	// ****************************
	// Constructors
	// ****************************

	public FallingObjectList(World world, Physics physics, Item item) {
		this.world = world;
		this.item = item;
		this.physics = physics;
	}

	// ****************************
	// Methods
	// ****************************

	public FallingObject getByBody(Body body)
	{
		Iterator<FallingObject> iteratorObjects = fallingObjects.iterator();

		while (iteratorObjects.hasNext()) {
			FallingObject fallingObject = iteratorObjects.next();

			if (fallingObject != null) {
				if (fallingObject.getBody().equals(body)) {
					return fallingObject;
				}
			}
		}
		// Body is no falling Object
		return null;
	}
	
	public void add(int numberOfObjects) {
		for (int i = 0; i < numberOfObjects; i++) {
			FallingObject fallingObject = new FallingObject(this);
			if (pause == true) {
				fallingObject.pause();
			}
			fallingObjects.add(fallingObject);
		}
	}

	public void add(float x) {
		FallingObject fallingObject = new FallingObject(this, new Vector2(x, Definitions.SCREEN_HEIGHT + item.getHeight()));
		if (pause == true) {
			fallingObject.pause();
		}
		fallingObjects.add(fallingObject);
	}
	
	public void remove(FallingObject fObject)
	{
		fObject.dispose();
		fallingObjects.remove(fObject);
	}

	public void pause() {
		Iterator<FallingObject> iteratorObjects = fallingObjects.iterator();

		while (iteratorObjects.hasNext()) {
			FallingObject fallingObject = iteratorObjects.next();

			if (fallingObject != null) {
				fallingObject.pause();
			}
		}
		pause = true;
	}

	public void resume() {
		Iterator<FallingObject> iteratorObjects = fallingObjects.iterator();

		while (iteratorObjects.hasNext()) {
			FallingObject fallingObject = iteratorObjects.next();

			if (fallingObject != null) {
				fallingObject.resume();
			}
		}
		pause = false;
	}

	public void update() {
		// First remove objects to remove
		//Iterator<FallingObject> i1 = removeObjects.iterator();

		// while (i1.hasNext()) {
		// FallingObject fallingObject = i1.next();
		// remove(fallingObject);
		// removeObjects.remove(fallingObject);
		// // Refresh iterator
		// i1 = removeObjects.iterator();
		// }
		
		// Now Update each object
		
		Iterator<FallingObject> i = fallingObjects.iterator();

		while (i.hasNext()) {
			FallingObject fallingObject = i.next();

			if (fallingObject != null) {
				if(!fallingObject.isRemoveable())
				{
					// UPDATE
					
					fallingObject.update();

					if (fallingObject.getBody().getPosition().y < -fallingObject
							.getSprite().getHeight() * Definitions.WORLD_TO_BOX) {
						remove(fallingObject);
						// Reinitialize theiterator otherwise this gets an error
						i = fallingObjects.iterator();
					}
				}
				else
				{
					// REMOVE
					
					remove(fallingObject);
					i = fallingObjects.iterator();
				}
			}
		}
	}
	
	

	public void draw(SpriteBatch batch) {
		Iterator<FallingObject> iteratorObjects = fallingObjects.iterator();

		while (iteratorObjects.hasNext()) {
			FallingObject fallingObject = iteratorObjects.next();
			fallingObject.draw(batch);
		}
	}

	public boolean Contains(Body body) {
		boolean contains = false;

		Iterator<FallingObject> iteratorObjects = fallingObjects.iterator();

		while (iteratorObjects.hasNext()) {
			FallingObject fallingObject = iteratorObjects.next();

			if (fallingObject != null) {
				if (fallingObject.getBody().equals(body)) {
					contains = true;
					break;
				}
			}
		}
		return contains;
	}
	
	public boolean Contains(FallingObject o)
	{
		boolean contains = false;

		Iterator<FallingObject> iteratorObjects = fallingObjects.iterator();

		while (iteratorObjects.hasNext()) {
			FallingObject fallingObject = iteratorObjects.next();

			if (fallingObject.equals(o)) {
				contains = true;
				break;
			}
		}
		return contains;
	}
	

	public void clear() {
		Iterator<FallingObject> iteratorObjects = fallingObjects.iterator();

		while (iteratorObjects.hasNext()) {
			FallingObject fallingObject = iteratorObjects.next();
			remove(fallingObject);
			iteratorObjects = fallingObjects.iterator();
		}
	}

	public void dispose() {
		clear();
	}

	// ****************************
	// Properties
	// ****************************

	public Physics getPhysics() {
		return physics;
	}
	
	public World getWorld(){
		return world;
	}

	public void setPhysics(Physics physics) {
		this.physics = physics;
	}
	
	public Item getItem() {
		return item;
	}
}
